﻿using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
using System.Web;

namespace TuChongPicView.Utils
{
        public class HttpUtils
        {
            private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
            private static readonly string DefaultUserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)";

            /// <summary>  
            /// 创建GET方式的HTTP请求  
            /// </summary>  
            /// <param name="url">请求的URL</param>  
            /// <param name="timeout">请求的超时时间</param>  
            /// <param name="userAgent">请求的客户端浏览器信息，可以为空</param>  
            /// <param name="cookies">随同HTTP请求发送的Cookie信息，如果不需要身份验证可以为空</param>  
            /// <returns></returns>  
            public static HttpWebResponse CreateGetHttpResponse(string url, int? timeout, string userAgent, CookieCollection cookies)
            {
                if (string.IsNullOrEmpty(url))
                {
                    throw new ArgumentNullException("url");
                }
                HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
                request.Method = "GET";
                request.UserAgent = DefaultUserAgent;
                //代理设置
                //if ((!String.IsNullOrEmpty(Constants.PROXY_HOST)) && (Constants.PROXY_PORT != null))
                //{
                //    WebProxy proxyObject = new WebProxy(Constants.PROXY_HOST, (int)Constants.PROXY_PORT);
                //    request.Proxy = proxyObject;
                //}
                if (!string.IsNullOrEmpty(userAgent))
                {
                    request.UserAgent = userAgent;
                }
                if (timeout.HasValue)
                {
                    request.Timeout = timeout.Value;
                }
                if (cookies != null)
                {
                    request.CookieContainer = new CookieContainer();

                    request.CookieContainer.Add(cookies);
                }
                else
                {
                    //if (CashierEntity.AuthenCode != null)
                    //{
                    //    cookies = new CookieCollection();
                    //    Cookie cookie = new Cookie();
                    //    cookie.Name = "acode";
                    //    cookie.Value = CashierEntity.AuthenCode;
                    //    cookie.Domain = ConfigEntity.ip;
                    //    cookies.Add(cookie);
                    //    request.CookieContainer = new CookieContainer();
                    //    request.CookieContainer.Add(cookies);
                    //}
                }
                return request.GetResponse() as HttpWebResponse;
            }

            /// <summary>  
            /// 创建POST方式的HTTP请求  
            /// </summary>  
            /// <param name="url">请求的URL</param>  
            /// <param name="parameters">随同请求POST的参数名称及参数值字典</param>  
            /// <param name="timeout">请求的超时时间</param> 
            /// <param name="userAgent">请求的客户端浏览器信息，可以为空</param>  
            /// <param name="requestEncoding">发送HTTP请求时所用的编码</param>  
            /// <param name="cookies">随同HTTP请求发送的Cookie信息，如果不需要身份验证可以为空</param>  
            /// <returns></returns>
            public static HttpWebResponse CreatePostHttpResponse(string url, IDictionary<string, string> parameters, int? timeout, string userAgent, Encoding requestEncoding, String ContentType, CookieCollection cookies)
            {
                if (string.IsNullOrEmpty(url))
                {
                    throw new ArgumentNullException("url");
                }
                if (requestEncoding == null)
                {
                    throw new ArgumentNullException("requestEncoding");
                }
                HttpWebRequest request = null;
                //如果是发送HTTPS请求  
                if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
                {
                    ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
                    request = WebRequest.Create(url) as HttpWebRequest;
                    request.ProtocolVersion = HttpVersion.Version10;
                }
                else
                {
                    request = WebRequest.Create(url) as HttpWebRequest;
                }
                request.Method = "POST";
                //代理设置
                //if ((!String.IsNullOrEmpty(Constants.PROXY_HOST)) && (Constants.PROXY_PORT != null))
                //{
                //    WebProxy proxyObject = new WebProxy(Constants.PROXY_HOST, (int)Constants.PROXY_PORT);
                //    request.Proxy = proxyObject;
                //}
                if (!string.IsNullOrEmpty(ContentType))
                {
                    request.ContentType = ContentType;
                }
                else
                {
                    request.ContentType = "application/x-www-form-urlencoded";
                }
                if (!string.IsNullOrEmpty(userAgent))
                {
                    request.UserAgent = userAgent;
                }
                else
                {
                    request.UserAgent = DefaultUserAgent;
                }

                if (timeout.HasValue)
                {
                    request.Timeout = timeout.Value;
                }
                if (cookies != null)
                {
                    request.CookieContainer = new CookieContainer();
                    request.CookieContainer.Add(cookies);
                }
                else
                {
                    //if (CashierEntity.AuthenCode != null)
                    //{
                    //    cookies = new CookieCollection();
                    //    Cookie cookie = new Cookie();
                    //    cookie.Name = "acode";
                    //    cookie.Value = CashierEntity.AuthenCode;
                    //    cookie.Domain = ConfigEntity.ip;
                    //    cookies.Add(cookie);
                    //    request.CookieContainer = new CookieContainer();
                    //    request.CookieContainer.Add(cookies);
                    //}
                }
                //如果需要POST数据   
                if (!(parameters == null || parameters.Count == 0))
                {
                    StringBuilder buffer = new StringBuilder();
                    int i = 0;
                    foreach (string key in parameters.Keys)
                    {
                        if (i > 0)
                        {
                            buffer.AppendFormat("&{0}={1}", key, parameters[key]);
                        }
                        else
                        {
                            buffer.AppendFormat("{0}={1}", key, parameters[key]);
                        }
                        i++;
                    }
                    byte[] data = requestEncoding.GetBytes(buffer.ToString());
                    using (Stream stream = request.GetRequestStream())
                    {
                        stream.Write(data, 0, data.Length);
                    }
                }
                //HttpRequestHeader head=new HttpRequestHeader();
                //request.Headers.Add(head, "value");
                return request.GetResponse() as HttpWebResponse;
            }

            /// <summary>
            /// post请求
            /// </summary>
            /// <param name="postUrl"></param>
            /// <param name="parameters"></param>
            /// <param name="dataEncode">可选</param>
            /// <returns></returns>
            public static string PostWebRequest(string postUrl, Dictionary<String, String> parameters, Encoding dataEncode)
            {
                string ret = string.Empty;
                try
                {
                    StringBuilder buffer = new StringBuilder();
                    if (parameters != null)
                    {
                        int i = 0;
                        foreach (string key in parameters.Keys)
                        {
                            if (i > 0)
                            {
                                buffer.AppendFormat("&{0}={1}", key, HttpUtility.UrlEncode(parameters[key]));
                            }
                            else
                            {
                                buffer.AppendFormat("{0}={1}", key, HttpUtility.UrlEncode(parameters[key]));
                            }
                            i++;
                        }
                    }
                    if (dataEncode == null) dataEncode = Encoding.UTF8;
                    byte[] byteArray = dataEncode.GetBytes(buffer.ToString()); //转化
                    HttpWebRequest webReq = (HttpWebRequest)WebRequest.Create(new Uri(postUrl));
                    webReq.Method = "POST";
                    webReq.ContentType = "application/x-www-form-urlencoded";

                    webReq.ContentLength = byteArray.Length;
                    Stream newStream = webReq.GetRequestStream();
                    newStream.Write(byteArray, 0, byteArray.Length);//写入参数
                    newStream.Close();
                    HttpWebResponse response = (HttpWebResponse)webReq.GetResponse();
                    StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.Default);
                    ret = sr.ReadToEnd();
                    sr.Close();
                    response.Close();
                    newStream.Close();
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
                return ret;
            }

            /// <summary>
            /// address 目标地址
            /// peremes post的参数
            /// 默认对发送的数据的值进行base64编码
            /// </summary>
            /// <returns></returns>
            public static String HttpPost(String address, Dictionary<String, String> peremes)
            {
                System.Net.ServicePointManager.DefaultConnectionLimit = 50;
                // Create a request using a URL that can receive a post. 
                if (!address.StartsWith("http")) address = "http://" + address;
                log.Debug("请求地址：" + address);
                WebRequest request = WebRequest.Create(address);
                // Set the Method property of the request to POST.
                request.Timeout = Constants.POST_TIMEOUT;//设置默认超时时间
                request.Method = "POST";
                //代理设置
                if ((!String.IsNullOrEmpty(Constants.PROXY_HOST)) && (Constants.PROXY_PORT != null))
                {
                    WebProxy proxyObject = new WebProxy(Constants.PROXY_HOST, (int)Constants.PROXY_PORT);
                    request.Proxy = proxyObject;
                }
                // Create POST data and convert it to a byte array.
                String st = "";
                foreach (KeyValuePair<String, String> tem in peremes)
                {
                    st = st + tem.Key.ToString() + "=" + HttpUtility.UrlEncode("" + tem.Value) + "&";
                }
                if (st.EndsWith("&"))
                    st = st.Remove(st.Length - 1);
                string postData = st;
                log.Debug("请求参数：" + st);
                //postData = Base64.EncodeBase64(postData);
                byte[] byteArray = Encoding.UTF8.GetBytes(postData);
                // Set the ContentType property of the WebRequest.
                request.ContentType = "application/x-www-form-urlencoded";//application/x-www-form-urlencoded
                                                                          // Set the ContentLength property of the WebRequest.
                request.ContentLength = byteArray.Length;
                //在这里对服务器返回异常进行处理
                WebResponse response = null;
                Stream dataStream = null;
                try
                {
                    // Get the request stream.
                    dataStream = request.GetRequestStream();
                    // Write the data to the request stream.
                    dataStream.Write(byteArray, 0, byteArray.Length);
                    // Close the Stream object.
                    dataStream.Close();
                    // Get the response.
                    response = request.GetResponse();
                }
                catch (Exception e)
                {
                    log.Debug(e.Message);
                }
                string responseFromServer = null;
                if (response != null)
                {
                    // Display the status.
                    log.Debug(((HttpWebResponse)response).StatusDescription);
                    // Get the stream containing content returned by the server.
                    dataStream = response.GetResponseStream();
                    // Read the content.
                    StreamReader reader = new StreamReader(dataStream);
                    // Display the content.
                    responseFromServer = reader.ReadToEnd();
                    log.Debug("请求相应：" + responseFromServer);
                    dataStream.Close();
                    response.Close();
                }
                return responseFromServer;
            }

            /// <summary>
            /// address 目标地址
            /// peremes post的参数
            /// timeout 超时时间 毫秒
            /// 默认对发送的数据的值进行base64编码
            /// </summary>
            /// <returns></returns>
            public static String HttpPost(String address, Dictionary<String, String> peremes, int timeout)
            {
                System.Net.ServicePointManager.DefaultConnectionLimit = 50;
                // Create a request using a URL that can receive a post. 
                if (!address.StartsWith("http")) address = "http://" + address;
                log.Debug("请求地址：" + address);
                WebRequest request = WebRequest.Create(address);
                // Set the Method property of the request to POST.
                request.Timeout = timeout <= 0 ? Constants.POST_TIMEOUT : timeout;//设置默认超时时间
                request.Method = "POST";
                //代理设置
                if ((!String.IsNullOrEmpty(Constants.PROXY_HOST)) && (Constants.PROXY_PORT != null))
                {
                    WebProxy proxyObject = new WebProxy(Constants.PROXY_HOST, (int)Constants.PROXY_PORT);
                    request.Proxy = proxyObject;
                }
                // Create POST data and convert it to a byte array.
                String st = "";
                foreach (KeyValuePair<String, String> tem in peremes)
                {
                    st = st + tem.Key.ToString() + "=" + HttpUtility.UrlEncode("" + tem.Value) + "&";
                }
                if (st.EndsWith("&"))
                    st = st.Remove(st.Length - 1);
                string postData = st;
                log.Debug("请求参数：" + st);
                //postData = Base64.EncodeBase64(postData);
                byte[] byteArray = Encoding.UTF8.GetBytes(postData);
                // Set the ContentType property of the WebRequest.
                request.ContentType = "application/x-www-form-urlencoded";//application/x-www-form-urlencoded
                                                                          // Set the ContentLength property of the WebRequest.
                request.ContentLength = byteArray.Length;
                //在这里对服务器返回异常进行处理
                WebResponse response = null;
                Stream dataStream = null;
                try
                {
                    // Get the request stream.
                    dataStream = request.GetRequestStream();
                    // Write the data to the request stream.
                    dataStream.Write(byteArray, 0, byteArray.Length);
                    // Close the Stream object.
                    dataStream.Close();
                    // Get the response.
                    response = request.GetResponse();
                }
                catch (Exception e)
                {
                    log.Debug(e.Message);
                }
                string responseFromServer = null;
                if (response != null)
                {
                    // Display the status.
                    log.Debug(((HttpWebResponse)response).StatusDescription);
                    // Get the stream containing content returned by the server.
                    dataStream = response.GetResponseStream();
                    // Read the content.
                    StreamReader reader = new StreamReader(dataStream);
                    // Display the content.
                    responseFromServer = reader.ReadToEnd();
                    log.Debug("请求相应：" + responseFromServer);
                    dataStream.Close();
                    response.Close();
                }
                return responseFromServer;
            }

            /// <summary>
            /// 发送图片到服务器
            /// </summary>
            /// <param name="url"></param>
            /// <param name="filePath"></param>
            /// <param name="parameters"></param>
            /// <param name="timeout"></param>
            /// <param name="requestEncoding"></param>
            /// <param name="ContentType"></param>
            /// <returns></returns>
            public static HttpWebResponse PostPic(string url, String filePath, IDictionary<string, string> parameters, int? timeout, Encoding requestEncoding, String ContentType)
            {
                string array = Convert.ToBase64String(imageToByteArray(filePath));

                if (string.IsNullOrEmpty(url))
                {
                    throw new ArgumentNullException("url");
                }
                if (requestEncoding == null)
                {
                    throw new ArgumentNullException("requestEncoding");
                }
                HttpWebRequest request = null;
                //如果是发送HTTPS请求  
                if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
                {
                    ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
                    request = WebRequest.Create(url) as HttpWebRequest;
                    request.ProtocolVersion = HttpVersion.Version10;
                }
                else
                {
                    request = WebRequest.Create(url) as HttpWebRequest;
                }
                request.Method = "POST";
                if (!string.IsNullOrEmpty(ContentType))
                {
                    request.ContentType = ContentType;
                }
                else
                {
                    request.ContentType = "application/x-www-form-urlencoded";
                }
                request.UserAgent = DefaultUserAgent;

                if (timeout.HasValue)
                {
                    request.Timeout = timeout.Value;
                }
                //如果需要POST数据   
                if (!(parameters == null || parameters.Count == 0))
                {
                    StringBuilder buffer = new StringBuilder();
                    int i = 0;
                    foreach (string key in parameters.Keys)
                    {
                        if (i > 0)
                        {
                            buffer.AppendFormat("&{0}={1}", key, parameters[key]);
                        }
                        else
                        {
                            buffer.AppendFormat("{0}={1}", key, parameters[key]);
                        }
                        i++;
                    }
                    byte[] data = requestEncoding.GetBytes(buffer.ToString());
                    using (Stream stream = request.GetRequestStream())
                    {
                        stream.Write(data, 0, data.Length);
                    }
                }
                return request.GetResponse() as HttpWebResponse;
            }

            /// <summary>
            /// 发送文件
            /// </summary>
            /// <param name="requestUri"></param>
            /// <param name="postData"></param>
            /// <param name="fileData"></param>
            /// <param name="fileName"></param>
            /// <param name="fileContentType"></param>
            /// <param name="fileFieldName"></param>
            /// <param name="cookies"></param>
            /// <param name="headers"></param>
            /// <returns></returns>
            public static WebResponse PostFile(Uri requestUri, NameValueCollection postData, Stream fileData, string fileName, string fileContentType, string fileFieldName, CookieContainer cookies, NameValueCollection headers)
            {
                HttpWebRequest webrequest = (HttpWebRequest)WebRequest.Create(requestUri);
                string ctype;
                fileContentType = string.IsNullOrEmpty(fileContentType) ? TryGetContentType(fileName, out ctype) ? ctype : "application/octet-stream" : fileContentType;
                fileFieldName = string.IsNullOrEmpty(fileFieldName) ? "file" : fileFieldName;
                if (headers != null)
                {
                    // set the headers
                    foreach (string key in headers.AllKeys)
                    {
                        string[] values = headers.GetValues(key);
                        if (values != null)
                            foreach (string value in values)
                            {
                                webrequest.Headers.Add(key, value);
                            }
                    }
                }
                webrequest.Method = "POST";
                if (cookies != null)
                {
                    webrequest.CookieContainer = cookies;
                }
                //else
                //{
                //    if (CashierEntity.AuthenCode != null)
                //    {
                //        cookies = new CookieContainer();
                //        CookieCollection cc= new CookieCollection();
                //        Cookie cookie = new Cookie();
                //        cookie.Name = "acode";
                //        cookie.Value = CashierEntity.AuthenCode;
                //        cookie.Domain = ConfigEntity.host.Replace("http://", "").Replace("/shopxx", "");
                //        cc.Add(cookie);
                //        request.CookieContainer = new CookieContainer();
                //        request.CookieContainer.Add(cookies);
                //    }
                //}
                string boundary = "----------" + DateTime.Now.Ticks.ToString("x", CultureInfo.InvariantCulture);
                webrequest.ContentType = "multipart/form-data; boundary=" + boundary;
                StringBuilder sbHeader = new StringBuilder();
                // add form fields, if any
                if (postData != null)
                {
                    foreach (string key in postData.AllKeys)
                    {
                        string[] values = postData.GetValues(key);
                        if (values != null)
                            foreach (string value in values)
                            {
                                sbHeader.AppendFormat("--{0}\r\n", boundary);
                                sbHeader.AppendFormat("Content-Disposition: form-data; name=\"{0}\";\r\n\r\n{1}\r\n", key, value);
                            }
                    }
                }
                if (fileData != null)
                {
                    sbHeader.AppendFormat("--{0}\r\n", boundary);
                    sbHeader.AppendFormat("Content-Disposition: form-data; name=\"{0}\"; {1}\r\n",
                        fileFieldName, string.IsNullOrEmpty(fileName) ? "" : string.Format(CultureInfo.InvariantCulture, "filename=\"{0}\";", Path.GetFileName(fileName)));
                    sbHeader.AppendFormat("Content-Type: {0}\r\n\r\n", fileContentType);
                }
                byte[] header = Encoding.UTF8.GetBytes(sbHeader.ToString());
                byte[] footer = Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n");
                long contentLength = header.Length + (fileData != null ? fileData.Length : 0) + footer.Length;
                webrequest.ContentLength = contentLength;
                using (Stream requestStream = webrequest.GetRequestStream())
                {
                    requestStream.Write(header, 0, header.Length);
                    if (fileData != null)
                    {
                        // write the file data, if any
                        byte[] buffer = new Byte[checked((uint)Math.Min(4096, (int)fileData.Length))];
                        int bytesRead;
                        while ((bytesRead = fileData.Read(buffer, 0, buffer.Length)) != 0)
                        {
                            requestStream.Write(buffer, 0, bytesRead);
                        }
                    }
                    // write footer
                    requestStream.Write(footer, 0, footer.Length);
                    return webrequest.GetResponse();
                }
            }

            /// <summary>
            /// 发送文件
            /// </summary>
            /// <param name="requestUri"></param>
            /// <param name="postData"></param>
            /// <param name="fileName"></param>
            /// <param name="fileContentType"></param>
            /// <param name="fileFieldName"></param>
            /// <param name="cookies"></param>
            /// <param name="headers"></param>
            /// <returns></returns>
            public static WebResponse PostFile(Uri requestUri, NameValueCollection postData, string fileName, string fileContentType, string fileFieldName, CookieContainer cookies, NameValueCollection headers)
            {
                using (FileStream fileData = File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    return PostFile(requestUri, postData, fileData, fileName, fileContentType, fileFieldName, cookies,
                                    headers);
                }
            }

            /// <summary>
            /// 获取文件类型
            /// </summary>
            /// <param name="fileName"></param>
            /// <param name="contentType"></param>
            /// <returns></returns>
            public static bool TryGetContentType(string fileName, out string contentType)
            {
                try
                {
                    RegistryKey key = Registry.ClassesRoot.OpenSubKey(@"MIME\Database\Content Type");
                    if (key != null)
                    {
                        foreach (string keyName in key.GetSubKeyNames())
                        {
                            RegistryKey subKey = key.OpenSubKey(keyName);
                            if (subKey != null)
                            {
                                string subKeyValue = (string)subKey.GetValue("Extension");

                                if (!string.IsNullOrEmpty(subKeyValue))
                                {
                                    if (string.Compare(Path.GetExtension(fileName).ToUpperInvariant(),
                                                        subKeyValue.ToUpperInvariant(), StringComparison.OrdinalIgnoreCase) ==
                                        0)
                                    {
                                        contentType = keyName;
                                        return true;
                                    }
                                }
                            }
                        }
                    }
                }
                catch
                {
                }
                contentType = "";
                return false;
            }

            private static String getIPfromPing(string ipAddress)
            {
                IPAddress ipaddress = new IPAddress(Byte.Parse(ipAddress));
                IPHostEntry dnstoip = new IPHostEntry();
                dnstoip = Dns.GetHostEntry(ipaddress);// Dns.Resolve(ipAddress.Replace("http://", ""));
                String ip = "";
                for (int i = 0; i < dnstoip.AddressList.Length; i++)
                {
                    if ((dnstoip.AddressList[i].ToString() != null) && (!dnstoip.AddressList[i].ToString().Equals("")))
                    {
                        ip = dnstoip.AddressList[i].ToString();
                    }
                }
                if (ip.Equals(""))
                {
                    IPAddress[] IPs = Dns.GetHostAddresses(ipAddress.Replace("http://", ""));
                    foreach (IPAddress ipd in IPs)
                    {
                        if ((ipd != null) && (!ipd.Equals("")))
                        {
                            ip = ipd.ToString();
                        }
                    }
                }
                return ip;
            }

            private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
            {
                return true; //总是接受  
            }

            private static byte[] imageToByteArray(string FilePath)
            {
            //using (MemoryStream ms = new MemoryStream())
            //{
            //    using (Image imageIn = Image.FromFile(FilePath))
            //    {
            //        using (Bitmap bmp = new Bitmap(imageIn))
            //        {
            //            bmp.Save(ms, imageIn.RawFormat);
            //        }
            //    }
            //    return ms.ToArray();
            //}

            return null;
            }

        }
}
